<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <title>
        springboot&#43;quartz定时任务（解决无法注入bean及持久化的问题） - seventeenw的博客
      </title>
    <head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport"
    content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
  <meta name="renderer" content="webkit">
  <meta http-equiv="Cache-Control" content="no-transform" />
  <meta http-equiv="Cache-Control" content="no-siteapp" />
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="format-detection" content="telephone=no,email=no,adress=no">
  
  <meta name="theme-color" content="#000000" />
  
  <meta http-equiv="window-target" content="_top" />
  
  
  <meta name="description" content="该文章解决的两个痛点： 1.无法注入bean 2.任务持久化问题 效果： 1.生成任务时自动生成任务到数据库 2.结束时任务自动删除 3.宕机后重启，会" />
  <meta name="generator" content="Hugo 0.59.1 with theme pure" />
  <title>springboot&#43;quartz定时任务（解决无法注入bean及持久化的问题） - seventeenw的博客</title>
  

  <link rel="stylesheet" href="https://seventeenw.gitee.io/blogs/css/style.css">
  <link rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/9.15.10/styles/github.min.css">
  <meta property="og:title" content="springboot&#43;quartz定时任务（解决无法注入bean及持久化的问题）" />
<meta property="og:description" content="该文章解决的两个痛点： 1.无法注入bean 2.任务持久化问题 效果： 1.生成任务时自动生成任务到数据库 2.结束时任务自动删除 3.宕机后重启，会" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://seventeenw.gitee.io/blogs/2020/06/springboot-quartz%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1%E8%A7%A3%E5%86%B3%E6%97%A0%E6%B3%95%E6%B3%A8%E5%85%A5%E5%8F%8A%E6%8C%81%E4%B9%85%E5%8C%96%E7%9A%84%E9%97%AE%E9%A2%98/" />
<meta property="article:published_time" content="2020-06-05T00:09:03+08:00" />
<meta property="article:modified_time" content="2020-06-05T00:09:03+08:00" />
<meta itemprop="name" content="springboot&#43;quartz定时任务（解决无法注入bean及持久化的问题）">
<meta itemprop="description" content="该文章解决的两个痛点： 1.无法注入bean 2.任务持久化问题 效果： 1.生成任务时自动生成任务到数据库 2.结束时任务自动删除 3.宕机后重启，会">


<meta itemprop="datePublished" content="2020-06-05T00:09:03&#43;08:00" />
<meta itemprop="dateModified" content="2020-06-05T00:09:03&#43;08:00" />
<meta itemprop="wordCount" content="1849">



<meta itemprop="keywords" content="" />
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="springboot&#43;quartz定时任务（解决无法注入bean及持久化的问题）"/>
<meta name="twitter:description" content="该文章解决的两个痛点： 1.无法注入bean 2.任务持久化问题 效果： 1.生成任务时自动生成任务到数据库 2.结束时任务自动删除 3.宕机后重启，会"/>

  <!--[if lte IE 9]>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.1.20170427/classList.min.js"></script>
    <![endif]-->

  <!--[if lt IE 9]>
      <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
      <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
    <![endif]-->

</head>
  </head>
  <body class="main-center theme-black" itemscope itemtype="http://schema.org/WebPage"><header class="header" itemscope itemtype="http://schema.org/WPHeader">
    <div class="slimContent">
      <div class="navbar-header">
        <div class="profile-block text-center">
          <a id="avatar" href="https://github.com/wengshiquan" target="_blank">
            <img class="img-circle img-rotate" src="https://seventeenw.gitee.io/blogs/avatar.png" width="200" height="200">
          </a>
          <h2 id="name" class="hidden-xs hidden-sm">17Null</h2>
          <h3 id="title" class="hidden-xs hidden-sm hidden-md">Java Developer</h3>
          <small id="location" class="text-muted hidden-xs hidden-sm"><i class="icon icon-map-marker"></i>Fuzhou, China</small>
        </div><div class="search" id="search-form-wrap">
    <form class="search-form sidebar-form">
        <div class="input-group">
            <input type="text" class="search-form-input form-control" placeholder="搜索" />
            <span class="input-group-btn">
                <button type="submit" class="search-form-submit btn btn-flat" onclick="return false;"><i
                        class="icon icon-search"></i></button>
            </span>
        </div>
        <div class="ins-search">
            <div class="ins-search-mask"></div>
            <div class="ins-search-container">
                <div class="ins-input-wrapper">
                    <input type="text" class="ins-search-input" placeholder="想要查找什么..."
                        x-webkit-speech />
                    <button type="button" class="close ins-close ins-selectable" data-dismiss="modal"
                        aria-label="Close"><span aria-hidden="true">×</span></button>
                </div>
                <div class="ins-section-wrapper">
                    <div class="ins-section-container"></div>
                </div>
            </div>
        </div>
    </form>
</div>
        <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#main-navbar" aria-controls="main-navbar" aria-expanded="false">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
      </div>
      <nav id="main-navbar" class="collapse navbar-collapse" itemscope itemtype="http://schema.org/SiteNavigationElement" role="navigation">
        <ul class="nav navbar-nav main-nav">
            <li class="menu-item menu-item-home">
                <a href="/blogs/">
                    <i class="icon icon-home-fill"></i>
                  <span class="menu-title">主页</span>
                </a>
            </li>
            <li class="menu-item menu-item-reprint">
                <a href="/blogs/reprint">
                    <i class="icon icon-star-fill"></i>
                  <span class="menu-title">转载</span>
                </a>
            </li>
            <li class="menu-item menu-item-about">
                <a href="/blogs/about">
                    <i class="icon icon-cup-fill"></i>
                  <span class="menu-title">关于</span>
                </a>
            </li>
        </ul>
      </nav>
    </div>
  </header>
  <aside class="sidebar" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    
      <div class="widget">
    <h3 class="widget-title">公告</h3>
    <div class="widget-body">
        <div id="board">
            <div class="content"><p>一直想做前端的java程序员~</p>
            </div>
        </div>
    </div>
</div>

      <div class="widget">
    <h3 class="widget-title"> 分类</h3>
    <div class="widget-body">
        <ul class="category-list">
        </ul>
    </div>
</div>
      <div class="widget">
    <h3 class="widget-title"> 标签</h3>
    <div class="widget-body">
        <ul class="tag-list">
            
        </ul>

    </div>
</div>
      
<div class="widget">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget-body">
        <ul class="recent-post-list list-unstyled no-thumbnail">
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://seventeenw.gitee.io/blogs/2020/06/vue-element-template-%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E7%9A%84%E5%BC%80%E5%8F%91%E6%B5%81%E7%A8%8B/" class="title">vue-element-template 从零开始的开发流程</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-06-25 22:51:58 &#43;0800 CST" itemprop="datePublished">2020-06-25</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://seventeenw.gitee.io/blogs/2020/06/vue-element-template-%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E7%9A%84%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97/" class="title">vue-element-template 从零开始的开发日志</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-06-25 22:49:21 &#43;0800 CST" itemprop="datePublished">2020-06-25</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://seventeenw.gitee.io/blogs/2020/06/idea-springboot%E5%9B%BE%E6%A0%87%E4%B8%8D%E6%AD%A3%E7%A1%AE/" class="title">IDEA Springboot图标不正确</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-06-25 15:06:28 &#43;0800 CST" itemprop="datePublished">2020-06-25</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://seventeenw.gitee.io/blogs/2020/06/%E6%A0%B9%E6%8D%AE%E6%95%B0%E6%8D%AE%E5%BA%93%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90%E5%AE%9E%E4%BD%93%E7%B1%BB%E7%AD%89%E6%96%87%E4%BB%B6/" class="title">根据数据库自动生成实体类等文件</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-06-10 11:07:41 &#43;0800 CST" itemprop="datePublished">2020-06-10</time>
                    </p>
                </div>
            </li>
            <li>
                <div class="item-inner">
                    <p class="item-title">
                        <a href="https://seventeenw.gitee.io/blogs/2020/06/springboot-quartz%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1%E8%A7%A3%E5%86%B3%E6%97%A0%E6%B3%95%E6%B3%A8%E5%85%A5%E5%8F%8A%E6%8C%81%E4%B9%85%E5%8C%96%E7%9A%84%E9%97%AE%E9%A2%98/" class="title">springboot&#43;quartz定时任务（解决无法注入bean及持久化的问题）</a>
                    </p>
                    <p class="item-date">
                        <time datetime="2020-06-05 00:09:03 &#43;0800 CST" itemprop="datePublished">2020-06-05</time>
                    </p>
                </div>
            </li>
        </ul>
    </div>
</div>
  </div>
</aside>

    
    
  <aside class="sidebar sidebar-toc collapse" id="collapseToc" itemscope itemtype="http://schema.org/WPSideBar">
    <div class="slimContent">
      <nav id="toc" class="article-toc">
        <h3 class="toc-title">文章目录</h3>
        <div class="toc-content always-active"><nav id="TableOfContents">
<ul>
<li>
<ul>
<li>
<ul>
<li>
<ul>
<li><a href="#该文章解决的两个痛点">该文章解决的两个痛点：</a></li>
<li><a href="#效果">效果：</a></li>
</ul></li>
<li><a href="#一-依赖">一、依赖</a></li>
<li><a href="#二-properties配置">二、properties配置</a></li>
<li><a href="#三-任务调度器-scheduler">三、任务调度器 Scheduler</a></li>
<li><a href="#四-quartzmanager-工具类">四、QuartzManager 工具类</a></li>
<li><a href="#五-自定义任务-job">五、自定义任务 Job</a></li>
</ul></li>
</ul></li>
</ul>
</nav>
        </div>
      </nav>
    </div>
  </aside>
<main class="main" role="main"><div class="content">
  <article id="-" class="article article-type-" itemscope
    itemtype="http://schema.org/BlogPosting">
    
    <div class="article-header">
      <h1 itemprop="name">
  <a
    class="article-title"
    href="/blogs/2020/06/springboot-quartz%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1%E8%A7%A3%E5%86%B3%E6%97%A0%E6%B3%95%E6%B3%A8%E5%85%A5%E5%8F%8A%E6%8C%81%E4%B9%85%E5%8C%96%E7%9A%84%E9%97%AE%E9%A2%98/"
    >springboot&#43;quartz定时任务（解决无法注入bean及持久化的问题）</a
  >
</h1>

      <div class="article-meta">
        <span class="article-date">
  <i class="icon icon-calendar-check"></i>
<a href="https://seventeenw.gitee.io/blogs/2020/06/springboot-quartz%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1%E8%A7%A3%E5%86%B3%E6%97%A0%E6%B3%95%E6%B3%A8%E5%85%A5%E5%8F%8A%E6%8C%81%E4%B9%85%E5%8C%96%E7%9A%84%E9%97%AE%E9%A2%98/" class="article-date">
  <time datetime="2020-06-05 00:09:03 &#43;0800 CST" itemprop="datePublished">2020-06-05</time>
</a>
</span>

        <span class="post-comment"><i class="icon icon-comment"></i> <a href="/blogs/2020/06/springboot-quartz%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1%E8%A7%A3%E5%86%B3%E6%97%A0%E6%B3%95%E6%B3%A8%E5%85%A5%E5%8F%8A%E6%8C%81%E4%B9%85%E5%8C%96%E7%9A%84%E9%97%AE%E9%A2%98/#comments"
            class="article-comment-link">评论</a></span>
		<span class="post-wordcount hidden-xs" itemprop="wordCount">字数统计:1849字</span>
		<span class="post-readcount hidden-xs" itemprop="timeRequired">阅读时长:4分 </span>
      </div>
    </div>
    <div class="article-entry marked-body" itemprop="articleBody">
      

<h4 id="该文章解决的两个痛点">该文章解决的两个痛点：</h4>

<p>1.无法注入bean</p>

<p>2.任务持久化问题</p>

<h4 id="效果">效果：</h4>

<p>1.生成任务时自动生成任务到数据库</p>

<p>2.结束时任务自动删除</p>

<p>3.宕机后重启，会自动重启任务</p>

<h3 id="一-依赖">一、依赖</h3>

<pre><code class="language-java">&lt;!--quartz定时调度依赖--&gt;
     &lt;dependency&gt;
            &lt;groupId&gt;org.quartz-scheduler&lt;/groupId&gt;
            &lt;artifactId&gt;quartz&lt;/artifactId&gt;
            &lt;version&gt;2.3.2&lt;/version&gt;
	 &lt;/dependency&gt;
</code></pre>

<h3 id="二-properties配置">二、properties配置</h3>

<pre><code class="language-properties">#=======================================================
#调度器配置
#=======================================================
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.instanceName=project1QuartzScheduler
org.quartz.scheduler.rmi.export=false
org.quartz.scheduler.rmi.proxy=false
#=======================================================
#线程池配置
#=======================================================
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=5
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
#=======================================================
#JobStore配置
#=======================================================
org.quartz.jobStore.misfireThreshold = 1000
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.isClustered=false
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.dataSource=myDS
#=======================================================
#数据库配置
#=======================================================
org.quartz.dataSource.myDS.driver=com.mysql.cj.jdbc.Driver
org.quartz.dataSource.myDS.URL=jdbc:mysql://127.0.0.1:3306/phoenix?characterEncoding=utf8&amp;characterSetResults=utf8&amp;autoReconnect=true&amp;failOverReadOnly=false&amp;useSSL=false&amp;serverTimezone=UTC
org.quartz.dataSource.myDS.user=root
org.quartz.dataSource.myDS.password=root
org.quartz.dataSource.myDS.maxConnections=10

</code></pre>

<h3 id="三-任务调度器-scheduler">三、任务调度器 Scheduler</h3>

<pre><code class="language-java">package com.nz.phoenix.irrigate.dao.impl;

import org.quartz.Scheduler;
import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;


@Configuration
public class QuartzConfig {
    @Autowired
    private JobFactory jobFactory;
    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;
    
    /**
     * 当触发器触发时，与之关联的任务被Scheduler中配置的JobFactory实例化，也就是每触发一次，就会创建一个任务的实例化对象
     * (如果缺省)则调用Job类的newInstance方法生成一个实例
     * (这里选择自定义)并将创建的Job实例化交给IoC管理
     * @return
     */
    @Bean
    public JobFactory jobFactory() {
        return new AdaptableJobFactory() {
            @Override
            protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
                Object jobInstance = super.createJobInstance(bundle);
                capableBeanFactory.autowireBean(jobInstance);
                return jobInstance;
            }
        };
    }

    /**
     * 配置SchedulerFactoryBean
     *
     * 将一个方法产生为Bean并交给Spring容器管理
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() throws Exception {
        // Spring提供SchedulerFactoryBean为Scheduler提供配置信息,并被Spring容器管理其生命周期
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setJobFactory(jobFactory);
        //这句一定要加！！！！不然properties配置不生效！！！！
        factory.setConfigLocation(new ClassPathResource(&quot;/quartz.properties&quot;));
        factory.setStartupDelay(1);
        factory.afterPropertiesSet();
        // 设置自定义Job Factory，用于Spring管理Job bean
        return factory;
    }

    @Bean(name = &quot;scheduler&quot;)
    public Scheduler scheduler() throws Exception {
        return schedulerFactoryBean().getScheduler();
    }
}

</code></pre>

<h3 id="四-quartzmanager-工具类">四、QuartzManager 工具类</h3>

<pre><code class="language-java">package com.nz.phoenix.irrigate.dao.impl;

import com.nz.phoenix.irrigate.service.impl.IrrPatrolPlanServiceImpl;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.support.TaskUtils;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Title:QuartzManager 工具类
 * @Description:com.nz.phoenix.irrigate.dao.impl
 * @Auther:wengshiquan
 * @Version:1.0
 * @create2020/6/3 9:22
 */

@Service
public class QuartzManager {
    private static final Logger logger = LoggerFactory.getLogger(TaskUtils.class);
    public static Scheduler scheduler;
    // 创建 schedulerFactory 工厂
    private static SchedulerFactory scheduleFactory = new StdSchedulerFactory();

    public QuartzManager(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

//    public static void main(String[] args) throws SchedulerException {
//        resumeJob();
//    }

    /**
     * 添加一个定时任务
     *
     * @param jobName          任务名
     * @param jobGroupName     任务组名
     * @param triggerName      触发器名
     * @param triggerGroupName 触发器组名
     * @param jobClass         任务类名
     * @param cron             时间
     */
    @SuppressWarnings({&quot;unchecked&quot;, &quot;rawtypes&quot;})
    public static void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName
            , Class&lt;? extends Job&gt; jobClass, String cron, Map&lt;String, Object&gt; params) throws Exception {

        Date beginDate = (Date) params.get(&quot;beginDate&quot;);
        Date endDate = (Date) params.get(&quot;endDate&quot;);
        cron = &quot;0/10 * * * * ?&quot;;
        if (!isValidExpression(cron)) {
            throw new Exception(&quot;时间有误，请联系管理员！&quot;);
        }
        try {
            // 任务名，任务组，任务执行类
            JobDetail job = JobBuilder.newJob(jobClass)

                    .withIdentity(jobName, jobGroupName).build();

            // 任务参数
            job.getJobDataMap().putAll(params);

//            if (null == beginDate) {
//                beginDate = new Date();
//                beginDate.setTime(beginDate.getTime() + 5000);
//            } else {
//                beginDate.setTime(beginDate.getTime() - 5000);
//            }
//            endDate.setTime(endDate.getTime() + 200000);
            // 触发器
            TriggerBuilder&lt;Trigger&gt; triggerBuilder = TriggerBuilder.newTrigger();

            triggerBuilder.startNow();
            // 触发器时间设定
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // 创建Trigger对象
            CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                    .withIdentity(triggerName, triggerGroupName)
                    .usingJobData(&quot;trigger1&quot;, &quot;这是jobDetail1的trigger&quot;)
                    .startNow()//立即生效
                    .startAt(beginDate)
                    .endAt(endDate)
                    .withSchedule(CronScheduleBuilder.cronSchedule(cron))
                    .withSchedule(
                            CronScheduleBuilder.cronSchedule(cron)
                                    .withMisfireHandlingInstructionDoNothing())
                    .build();

            // 调度容器设置JobDetail和Trigger
            scheduler.scheduleJob(job, cronTrigger);

            // 启动
            if (!scheduler.isShutdown()) {
                scheduler.start();
                System.out.println(&quot;---定时任务开启  jobName:+&quot;+ jobName +&quot; ---&quot;);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 修改一个任务的触发时间
     *
     * @param triggerName      触发器名
     * @param triggerGroupName 触发器组名
     * @param cron             时间设置，参考quartz说明文档
     */
    public void modifyJobTime(String triggerName, String triggerGroupName, String cron) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            if (trigger == null) {
                return;
            }

            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(cron)) {
                // 触发器
                TriggerBuilder&lt;Trigger&gt; triggerBuilder = TriggerBuilder.newTrigger();
                // 触发器名,触发器组
                triggerBuilder.withIdentity(triggerName, triggerGroupName);
                triggerBuilder.startNow();
                // 触发器时间设定
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
                // 创建Trigger对象
                trigger = (CronTrigger) triggerBuilder.build();
                // 方式一 ：修改一个任务的触发时间
                scheduler.rescheduleJob(triggerKey, trigger);

            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 移除一个任务
     *
     * @param jobName          任务名
     * @param jobGroupName     任务组名
     * @param triggerName      触发器名
     * @param triggerGroupName 触发器组名
     */
    public static void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) {
        try {

            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);

            // 停止触发器
            scheduler.pauseTrigger(triggerKey);
            // 移除触发器
            scheduler.unscheduleJob(triggerKey);
            // 删除任务
            scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取任务是否存在
     * &lt;p&gt;
     * STATE_BLOCKED 4 阻塞
     * STATE_COMPLETE 2 完成
     * STATE_ERROR 3 错误
     * STATE_NONE -1 不存在
     * STATE_NORMAL 0 正常
     * STATE_PAUSED 1 暂停
     */
    public Boolean notExists(String triggerName, String triggerGroupName) {
        try {
            return scheduler.getTriggerState(TriggerKey.triggerKey(triggerName, triggerGroupName)) == Trigger.TriggerState.NONE;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 启动所有定时任务
     */
    public static void startJobs() {
        try {
            Scheduler scheduler = scheduleFactory.getScheduler();
            scheduler.start();
        } catch (SchedulerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 关闭所有定时任务
     */
    public static void stopJobs() {
        try {
            Scheduler scheduler = scheduleFactory.getScheduler();
            if (!scheduler.isShutdown()) {
                scheduler.shutdown();
            }
        } catch (SchedulerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    //从数据库中找到已经存在的job，并重新开户调度
    public static void resumeJob() {
        try {
            SchedulerFactory schedulerFactory = new StdSchedulerFactory();
            Scheduler scheduler = schedulerFactory.getScheduler();
            //获取调度器中所有的触发器组
            List&lt;String&gt; triggerGroups = scheduler.getTriggerGroupNames();
            //遍历获取每个触发器组
            for (int i = 0; i &lt; triggerGroups.size(); i++) {
                List&lt;String&gt; triggers = scheduler.getTriggerGroupNames();
                //遍历每个触发器组
                for (int j = 0; j &lt; triggers.size(); j++) {
                    //获取每个触发器
                    Trigger tg = scheduler.getTrigger(new TriggerKey(triggers
                            .get(j), triggerGroups.get(i)));
                    // 重新恢复在tgroup1组中，名为trigger1_1触发器的运行
//                    if (tg instanceof SimpleTrigger
//                            &amp;&amp; tg.getDescription().equals(&quot;group1.trigger1&quot;)) {
                    //恢复运行
                    scheduler.resumeJob(new JobKey(triggers.get(j),
                            triggerGroups.get(i)));
//                    }
                }

            }
            scheduler.start();
        } catch (Exception e) {
            e.printStackTrace();

        }
    }


    /**
     * 判断cron时间表达式正确性
     *
     * @param cronExpression
     * @return
     */
    public static boolean isValidExpression(final String cronExpression) {
        CronTriggerImpl trigger = new CronTriggerImpl();
        try {
            trigger.setCronExpression(cronExpression);
            Date date = trigger.computeFirstFireTime(null);
            return date != null &amp;&amp; date.after(new Date());
        } catch (ParseException e) {
            logger.error(e.getMessage(), e);
        }
        return false;
    }
}
</code></pre>

<h3 id="五-自定义任务-job">五、自定义任务 Job</h3>

<pre><code class="language-java">package com.nz.phoenix.irrigate.dao.impl;

import com.nz.phoenix.common.utils.Identifier;
import com.nz.phoenix.entity.irrigate.IrrPatrolPlan;
import com.nz.phoenix.entity.irrigate.IrrPatrolTask;
import com.nz.phoenix.entity.sm.User;
import com.nz.phoenix.enums.StateEnums;
import com.nz.phoenix.irrigate.dao.IIrrPatrolPersonDao;
import com.nz.phoenix.irrigate.dao.IIrrPatrolPlanDao;
import com.nz.phoenix.irrigate.dao.IIrrPatrolTaskDao;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Random;


@Service
public class SftpJob extends QuartzJobBean {

	//此处可自行注入
    @Autowired


    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        // 传入的参数
        JobKey key = context.getJobDetail().getKey();
        JobDataMap dataMap = context.getJobDetail().getJobDataMap();
        String printTime = new SimpleDateFormat(&quot;yy-MM-dd HH-mm-ss&quot;).format(new Date());
        System.err.println(&quot;PrintWordsJob start at:&quot; + printTime + &quot;, prints: Hello Job-&quot; + new Random().nextInt(100));

        System.out.println(&quot;Instance &quot; + key + &quot; of DumbJob says: &quot;  + &quot;, and val is: &quot; + cron);

    }
}

</code></pre>

    </div>
  </article>
<section id="comments">
</section>

</div><nav class="bar bar-footer clearfix" data-stick-bottom>
    <div class="bar-inner">
        <ul class="pager pull-left">
            <li class="prev">
                <a href="https://seventeenw.gitee.io/blogs/2020/05/cron/" title="Cron"><i
                        class="icon icon-angle-left"
                        aria-hidden="true"></i><span>&nbsp;&nbsp;上一篇</span></a>
            </li>
            <li class="next">
                <a href="https://seventeenw.gitee.io/blogs/2020/06/%E6%A0%B9%E6%8D%AE%E6%95%B0%E6%8D%AE%E5%BA%93%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90%E5%AE%9E%E4%BD%93%E7%B1%BB%E7%AD%89%E6%96%87%E4%BB%B6/"
                    title="根据数据库自动生成实体类等文件"><span>下一篇&nbsp;&nbsp;</span><i
                        class="icon icon-angle-right" aria-hidden="true"></i></a>
            </li>
            
            <li class="toggle-toc">
                <a class="toggle-btn collapsed" data-toggle="collapse" href="#collapseToc" aria-expanded="false"
                    title="文章目录" role="button">
                    <span>[&nbsp;</span><span>文章目录</span>
                    <i class="text-collapsed icon icon-anchor"></i>
                    <i class="text-in icon icon-close"></i>
                    <span>]</span>
                </a>
            </li>
        </ul>
        <div class="bar-right">
            <div class="share-component" data-sites="weibo,qq,wechat,facebook,twitter"
                data-mobile-sites="weibo,qq,qzone"></div>
        </div>
    </div>
</nav>
</main><footer class="footer" itemscope itemtype="http://schema.org/WPFooter">
<ul class="social-links">
    <li><a href="https://github.com/wengshiquan" target="_blank" title="github" data-toggle=tooltip data-placement=top >
            <i class="icon icon-github"></i></a></li>
    <li><a href="https://seventeenw.gitee.io/index.xml" target="_blank" title="rss" data-toggle=tooltip data-placement=top >
            <i class="icon icon-rss"></i></a></li>
    <li><a href="https://gitee.com/seventeenw" target="_blank" title="tags" data-toggle=tooltip data-placement=top >
            <i class="icon icon-tags"></i></a></li>
</ul>
  <div class="copyright">
    &copy;2017  -
    2020
    <div class="publishby">
        Theme by <a href="https://github.com/xiaoheiAh" target="_blank"> xiaoheiAh </a>base on<a href="https://github.com/xiaoheiAh/hugo-theme-pure" target="_blank"> pure</a>.
    </div>
  </div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<script>
   window.jQuery || document.write('<script src="js/jquery.min.js"><\/script>')
</script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/highlight.min.js"></script>
<script type="text/javascript" src="https://cdn.staticfile.org/highlight.js/9.15.10/languages/rust.min.js"></script>
<script type="text/javascript"
   src="https://cdn.staticfile.org/highlight.js/9.15.10/languages/dockerfile.min.js"></script>
<script>
hljs.configure({
  tabReplace: '    ', 
  classPrefix: ''     
                      
})
hljs.initHighlightingOnLoad();
</script>
<script type="text/javascript" src="https://seventeenw.gitee.io/blogs/js/application.js"></script>
<script type="text/javascript" src="https://seventeenw.gitee.io/blogs/js/plugin.js"></script>
<script>
      (function (window) {
          var INSIGHT_CONFIG = {
              TRANSLATION: {
                  POSTS: '文章',
                  PAGES: '页面',
                  CATEGORIES: '分类',
                  TAGS: '标签',
                  UNTITLED: '(未命名)',
              },
              ROOT_URL: 'https:\/\/seventeenw.gitee.io\/blogs',
              CONTENT_URL: 'https:\/\/seventeenw.gitee.io\/blogs\/searchindex.json ',
          };
          window.INSIGHT_CONFIG = INSIGHT_CONFIG;
      })(window);
      </script>
<script type="text/javascript" src="https://seventeenw.gitee.io/blogs/js/insight.js"></script>

  </body>
</html>
